import {defaultStyle} from '@/components1/default-style';
export const initDraw = function (ctx,list,values) {
    setTimeout(() => {
        console.log('drawing....');
        ctx.clearRect(0,0,2000,2000);
        list.forEach((drawData,index) =>{
            if(!drawData.name){
                drawData.name = (index + 1) +'';
            }
            ctx.save();
            let drawList = drawData.drawList;
            useStyle(ctx,defaultStyle);
            drawList.forEach((drawParam,index) => {
                drawParam.g = {
                    offsetX: drawData.offsetX | 0,
                    offsetY: drawData.offsetY | 0,
                    parentNames: [],
                }
                drawParam.g.style = assign(defaultStyle,drawParam.style);
                if(!drawParam.name){
                    drawParam.name = drawData.name + '-' + (index + 1);
                }
                draw(drawParam,ctx,values);
            });
            ctx.restore();
        });

    },100);
}
export const draw = function (drawParam,ctx,values){
    ctx.save();
    if(drawParam.style){
        useStyle(ctx,drawParam.g.style);
    }
    if(drawParam.styleByValue){
        let value = findValue(drawParam.name,values,null);
        useStyle(ctx,drawParam.styleByValue(value));
    }
    if(drawParam.basePoint){
        let x = drawParam.basePoint[0] | 0,y= drawParam.basePoint[1] | 0;
        drawParam.g.offsetX += x;
        drawParam.g.offsetY += y;
    }
    ctx.translate(drawParam.g.offsetX, drawParam.g.offsetY);
    if(drawParam.type === 'text'){
        drawText(drawParam,ctx,values);
    }else if(drawParam.type === 'pos'){
        ctx.beginPath();
        ctx.arc(0,0,5,0,Math.PI * 2);
        ctx.fill();
    }else if(drawParam.type === 'rect'){
        drawRect(drawParam,ctx);
    }else if(drawParam.type === 'container'){
        drawContainer(drawParam,ctx,values);
    } else if(drawParam.type === 'circle'){
        drawCircle(drawParam,ctx);
    }else if(drawParam.type === 'arc'){
        drawArc(drawParam,ctx);
    }else if(drawParam.type === 'valve'){
        drawValve(drawParam,ctx);
    }else if(drawParam.type === 'line'){
        drawLine(drawParam,ctx);
    }else if(drawParam.type === 'table'){
        drawTable(drawParam,ctx,values);
    }else if(drawParam.type === 'triangle'){
        drawTriangle(drawParam,ctx);
    }else if(drawParam.type === 'translate'){
        ctx.translate(drawParam.x,drawParam.y);
    }else if(drawParam.type === 'btn'){
        drawBtn(drawParam,ctx);
    }
    ctx.restore();
    if(drawParam.children){
        drawParam.children.forEach((child,index) => {
            if(!child.name){
                child.name = drawParam.name +'-' + (index + 1);
            }
            child.g = {
                offsetX: drawParam.g.offsetX,
                offsetY: drawParam.g.offsetY,
                parentNames: [].concat(drawParam.g.parentNames),
                style: {},
            }
            child.g.style = assign(drawParam.g.style,child.style);
            child.g.parentNames.push(drawParam.name);
            if(drawParam.type === 'translate'){
                child.g.offsetX += drawParam.x | 0;
                child.g.offsetY += drawParam.y | 0;
            }
            draw(child,ctx,values);
        });
    }
}
function getStart(drawParam){
    let startXY = [0,0];
    if(drawParam.startX){
        startXY[0] = drawParam.startX;
    }
    if(drawParam.startY){
        startXY[1] = drawParam.startY;
    }
    return startXY;
}
function drawBtn(drawParam,ctx){
    let xy = getStart(drawParam);
    let defaultColor = 'rgb(52,133,252)';
    if(drawParam.backColor){
        defaultColor = drawParam.backColor;
    }
    ctx.fillStyle = defaultColor;
    ctx.fillRect(xy[0],xy[1],drawParam.width,drawParam.height)
    ctx.lineWidth = 3;
    ctx.strokeStyle = drawParam.borderStyle
    if(drawParam.border){
        ctx.save();
        let borderStyle = assign(defaultStyle.borderStyle,drawParam.borderStyle);
        useStyle(ctx,borderStyle);
        ctx.strokeRect(xy[0],xy[1],drawParam.width,drawParam.height)
        ctx.restore();
    }
    useStyle(ctx,drawParam.fontStyle);
    let textAlign = ctx.textAlign;
    let textX,textY = drawParam.height / 2 + 2;
    if(['left','start'].includes(textAlign)){
        textX = xy[0] + 2;
    }else if(['right','end'].includes(textAlign)){
        textX = xy[0] + drawParam.width - 2;
    }else {
        textX = (xy[0] * 2 + drawParam.width)/2;
    }
    if(drawParam.fontStyle && drawParam.fontStyle.isStroke){
        ctx.strokeText(drawParam.label,textX,textY);
    }else {
        ctx.fillText(drawParam.label,textX,textY);
    }
}
function drawTriangle(drawParam,ctx){
    if('left' === drawParam.direction){
        ctx.rotate(-Math.PI/2);
    }else if('bottom' === drawParam.direction){
        ctx.rotate(Math.PI);
    }else if('right' === drawParam.direction){
        ctx.rotate(Math.PI/2);
    }
    ctx.beginPath();
    ctx.moveTo(0,0);
    ctx.lineTo(drawParam.width/2,drawParam.height);
    ctx.lineTo(-drawParam.width/2,drawParam.height);
    ctx.lineTo(0,0);
    if(drawParam.isFill){
        ctx.fill();
    }else {
        ctx.stroke();
    }
}
function drawText(drawParam,ctx,values){
    let x = drawParam.startX | 0, y= drawParam.startY | 0;
    let text = drawParam.text;
    if(typeof text !== 'undefined'){
        text = findText(drawParam.text,values);
    }
    if(drawParam.name){
        text = findValue(drawParam.name,values,text);
    }
    //todo 判断text === undefined, 单行文字与多行文字使用嵌套定义
    if(text){
        if(drawParam.isStroke){
            ctx.strokeText(text,x, y);
        }else {
            ctx.fillText(text,x, y);
        }
    }
    let textList = drawParam.textList;
    if(!textList){
        return;
    }
    textList.forEach((txt,index) =>{
        if(!txt.name){
            txt.name = drawParam.name +'-' + (index + 1);
        }
        text = txt.text;
        if(typeof text === 'undefined'){
            text = findValue(txt.name,values,'');
        }else {
            text = findText(txt.text,values);
        }

        txt.g = {
            offsetX: drawParam.g.offsetX,
            offsetY: drawParam.g.offsetY,
            parentNames: [].concat(drawParam.g.parentNames),
            style: assign(drawParam.g.style,txt.style),
        }
        txt.g.parentNames.push(drawParam.name);
        if(text){
            ctx.save();
            useStyle(ctx,txt.g.style);
            let isStroke = txt.isStroke;
            if(typeof(txt.isStroke) === 'undefined'){
                isStroke = drawParam.isStroke;
            }
            //判断坐标是相对还是绝对
            let txtX = txt.x | 0,txtY = txt.y | 0;

            if(txt.isAbsolute){
                txtX = txtX - drawParam.g.offsetX;
                txtY = txtY - drawParam.g.offsetY;
            }
            if(isStroke){
                ctx.strokeText(text,txtX,txtY);
            }else {
                ctx.fillText(text,txtX,txtY);
            }
            ctx.restore();
        }
    });
}
function drawTable(drawParam,ctx,values){
    ctx.lineCap = 'round';
    let x = 0,y=0;
    if(drawParam.startX){
        x = drawParam.startX;
    }
    if(drawParam.startY){
        y =drawParam.startY;
    }
    if(drawParam.clear){
      ctx.clearRect(x,y,drawParam.width,drawParam.height);
    }
    let rowData = drawParam.data;
    let colWidth;
    let column = drawParam.column;
    let colCount = drawParam.col;
    let rowCount = drawParam.row;
    if(column && column.length > 0){
        colCount = column.length;
        let widthLessThen1 = 0, widthGreatThen1 = 0, countOfWithoutWidth = 0;
        column.forEach(colInfo => {
            if(!colInfo.width){
                countOfWithoutWidth++;
            }else if(colInfo.width > 1){
                widthGreatThen1 +=colInfo.width;
            }else if(colInfo.width > 0){
                widthLessThen1 += colInfo.width;
            }else {
                countOfWithoutWidth++;
            }
        });
        if(countOfWithoutWidth > 0 && widthLessThen1 >0){
            console.error('表格宽度设置不能同时配置比率与缺省：' + drawParam.name);
            return;
        }
        //todo 先假设只能配其中一种（不配，大于1的宽度，小于1的占比）
        if(countOfWithoutWidth >0){
            //没有配置宽度：使用平均宽度
        }else{
            let baseNum = widthLessThen1 > 0 ? widthLessThen1 : widthGreatThen1;
            column.forEach(colInfo => {
                colInfo.width = colInfo.width * drawParam.width / baseNum;
            });
        }
    }
    if(colCount){
        colWidth = drawParam.width / colCount;
    }else{
        colCount = column.length;
    }
    if(!rowCount){
        rowCount = rowData.length;
    }
    let rowHeight = drawParam.height / rowCount;

    //let colWidth = drawParam.width / drawParam.col;
    if(typeof drawParam.showLine !== 'undefined' && !drawParam.showLine){
        drawParam.rowLine = false;
        drawParam.colLine = false;
    }
    if(typeof drawParam.rowLine === 'undefined' || drawParam.rowLine){
        ctx.beginPath();
        for(let r=0;r<=rowCount;r++){
            let checky = checkxy(r*rowHeight + y,ctx);
            checky = r*rowHeight + y;
            if(r === 13) {
                //checky += 0.5;
                ctx.moveTo(x,checky);
                ctx.lineTo(drawParam.width + x,checky);
            }else{
                ctx.moveTo(x,checky);
                ctx.lineTo(drawParam.width + x,checky);
            }
        }
        ctx.stroke();
    }
    let offsetX = x;
    for(let c=0;c<=colCount;c++){
        if(typeof  drawParam.colLine === 'undefined' || drawParam.colLine){
            ctx.beginPath();
            ctx.moveTo(offsetX,y);
            ctx.lineTo(offsetX,drawParam.height + y);
            ctx.stroke();
        }
        if(c < colCount){
            ctx.save();
            let w = colWidth;
            if(column && column[c] && column[c].width){
                w = column[c].width;
            }
            let nextColX = offsetX + w;
            if(column && column[c]){
                useStyle(ctx,column[c].style);
            }
            let textX = offsetX + 3;
            let textAlign = ctx.textAlign;
            if(['end','right'].includes(textAlign)){
                textX = nextColX - 3;
                console.log(textX);
            }else if('center' === textAlign){
                textX = (offsetX + nextColX)/2;
            }
            if(rowData){
                for(let r=0; r< rowCount; r++){
                    if(r < rowData.length){
                        let row = rowData[r];
                        let colData = row[c];
                        let colText = colData;
                        if(typeof colData === 'object'){
                            colText = findValue(colData.name,values,colData.text);
                        }
                        if(row && (row[c] || row[c] === 0)){
                            let text = row[c];
                            let textY = rowHeight * (1 + 2 * r) / 2 + 1 + y;
                            if(typeof text === 'string' || typeof text === 'number'){
                                ctx.fillText(text + '', textX,textY);
                            }else {
                                ctx.save();
                                useStyle(ctx,text.style);
                                if(text.styleByValue){
                                    let styleByValue = text.styleByValue(colText);
                                    useStyle(ctx,styleByValue);
                                }
                                ctx.fillText(colText +'', textX,textY);
                                ctx.restore();
                            }
                        }
                    }
                }
            }
            offsetX = nextColX;
            ctx.restore();
        }
    }
}
function drawLine(drawParam,ctx){
    let pathList = drawParam.pathList;
    if(!pathList){
        return;
    }
    ctx.beginPath();
    pathList.forEach(path => {
        let x = path.x | 0, y = path.y | 0;
        if(path.type === 'moveTo'){
            ctx.moveTo(x,y);
        }else if(path.type === 'lineTo'){
            ctx.lineTo(x,y);
        }else if(path.type === 'close'){
            ctx.closePath();
        }else if(path.type === 'arcTo'){
            ctx.arcTo(path.x1,path.y1,path.x2,path.y2,path.r);
        }
    });
    if(drawParam.isFill){
        ctx.fill();
    }else {
        ctx.stroke();
    }

}
function drawValve(drawParam,ctx){
    if(drawParam.crossStart){
        ctx.translate(-drawParam.width/2,-drawParam.height/2);
    }
    ctx.beginPath();
    ctx.moveTo(0,0);
    if('x' === drawParam.direction){
        ctx.lineTo( 0,drawParam.height);
        ctx.lineTo(drawParam.width,0);
    }else {
        ctx.lineTo(drawParam.width,0);
        ctx.lineTo( 0,drawParam.height);
    }
    ctx.lineTo(drawParam.width,drawParam.height);
    ctx.lineTo(0,0);
    if(drawParam.isFill){
        ctx.fill();
    }else {
        ctx.stroke();
    }
    if(drawParam.crossStart){
        ctx.translate(drawParam.width/2,drawParam.height/2);
    }
}
function drawArc(drawParam,ctx){
    let ox = 0,oy=0;
    if(drawParam.ox){
        ox = drawParam.ox;
    }
    if(drawParam.oy){
        oy = drawParam.oy;
    }
    ctx.beginPath()
    ctx.arc(ox,oy,drawParam.radius,drawParam.start,drawParam.end);
    if(drawParam.isFill){
        ctx.fill()
    }else {
        if(drawParam.close){
            ctx.closePath();
        }
        ctx.stroke();
    }
}
function drawCircle(drawParam,ctx){
    let ox = drawParam.ox | 0, oy = drawParam.oy | 0, startAngle = drawParam.startAngle | 0, endAngle = 2* Math.PI;
    if(typeof drawParam.endAngle !== "undefined"){
        endAngle = drawParam.endAngle;
    }
    ctx.beginPath()
    let r = drawParam.radius;
    if(r){
        ctx.arc(ox,oy,r,startAngle,endAngle);
    }else if(drawParam.radiusX && drawParam.radiusY) {
        r = drawParam.radiusY
        let scaleX = drawParam.radiusX / r;
        ctx.scale(scaleX, 1);
        ctx.arc(ox,oy,r,startAngle,endAngle);
    }else {
        console.log('圆弧半径设置错误！');
        return;
    }
    if(drawParam.isFill){
        ctx.fill()
    }else {
        ctx.stroke();
    }
}
function drawContainer(drawParam,ctx,values){
    let x = drawParam.startX | 0, y= drawParam.startY | 0;
    let liquidLevelMax = drawParam.liquidMax;
    let liquidLevelValue = drawParam.liquidValue;
    let endY = -drawParam.height;
    if(!liquidLevelValue){
        liquidLevelValue = findValue(drawParam.name,values,0);
    }
    let direction = drawParam.direction;
    if(typeof direction === 'undefined'){
        direction = 'y';
    }
    if(typeof liquidLevelMax === 'undefined'){
        if(direction === 'y'){
            liquidLevelMax = drawParam.height;
        }else {
            liquidLevelMax = drawParam.width;
        }
    }
    let liquidX,liquidY;
    let liquidRate = liquidLevelValue / liquidLevelMax;
    if(direction === 'y'){
        liquidX = drawParam.width;
        liquidY = liquidRate * endY;
    }else {
        liquidX = liquidRate * drawParam.width;
        liquidY = drawParam.height;
    }
    if(drawParam.styleByValue){
        useStyle(ctx,drawParam.styleByValue(liquidRate));
    }
    if(drawParam.clear){
        ctx.clearRect(x,y,drawParam.width,endY);
    }
    //画容器外框矩形
    ctx.strokeRect(x,y,drawParam.width,endY);
    //画液位矩形
    ctx.fillRect(x,y,liquidX,liquidY);
}

function drawRect(drawParam,ctx){
    let x = drawParam.startX | 0, y= drawParam.startY | 0;
    let leanX = 0;
    let leanY = 0;
    if(drawParam.leanX){
        leanX = drawParam.leanX;
    }
    if(drawParam.leanY){
        leanY = drawParam.leanY;
    }
    ctx.transform(1,leanX,leanY,1,0,0);
    if(drawParam.clear){
        ctx.clearRect(x,y,drawParam.width,drawParam.height)
    }
    if(drawParam.isFill){
        ctx.fillRect(x,y,drawParam.width,drawParam.height)
    }else {
        ctx.strokeRect(x,y,drawParam.width,drawParam.height);
    }
}
export const reDraw = function(ctx,drawData,name,value){
    let drawList = drawData.drawList;
    useStyle(ctx,defaultStyle);
    let drawParam = findEle(drawList,name);
    if(!drawParam){
        console.log('没有找到图形元素，名称：' + name);
        return;
    }
    console.log('=========================');
    console.log(value);
    console.log(drawParam);
    drawParam.style.fillStyle = '#f00';
    //draw(drawParam,ctx);
    initDraw(drawData,ctx);
}
function findEle(drawList,name){
    let len = drawList.length;
    for(let i=0;i<len;i++){
        let drawParam = drawList[i];
        if(name === drawParam.name){
            return drawParam;
        }else if(drawParam.children){
            let childFind = findEle(drawParam.children,name);
            if(childFind){
                return childFind;
            }
        }
    }
    drawList.forEach(drawParam => {
        if(name === drawParam.name){
            return drawParam;
        }
    })
}

function useStyle(ctx,style){
    if(style){
        for(let key in style){
            ctx[key] = style[key];
        }
        if(style.lineDash){
            ctx.setLineDash(style.lineDash)
        }
    }
}
function copy(target,source1,source2){
    if(source1){
        for(let key in source1){
            target[key] = source1[key];
        }
    }
    if(source2){
        for(let key in source2){
            target[key] = source2[key];
        }
    }
    return target;
}
function assign(source1,source2){
    return copy({},source1,source2);
}
function findValue(pointName,values,defaultValue){
    if(pointName){
        let pointValue = values[pointName];
        if(typeof pointValue != "undefined"){
            defaultValue = pointValue;
        }
    }
    return defaultValue;
}
function findText(text,values){
    let startIndex = text.indexOf('{{');
    let endIndex = text.indexOf('}}');
    if(startIndex === -1 || endIndex === -1){
        return text;
    }
    if(endIndex - 2 > startIndex){
        let name = text.substring(startIndex + 2,endIndex);
        let value = findValue(name,values,name);
        return text.replace('{{' + name + '}}', value);
    }else {
        return text;
    }
}
function checkxy(value,ctx){
    //
    let lineWidth = ctx.lineWidth;
    if(lineWidth % 2 === 0){
        return value;
    }
    //将值变成 .5结尾
    let value1 = Math.ceil(value * 2);
    if(value1 % 2 === 0){
        value1 -= 1;
    }
    return value1/2;
}

Date.prototype.format = function(fmt) {
    var o = {
        "M+" : this.getMonth()+1,                 //月份
        "d+" : this.getDate(),                    //日
        "h+" : this.getHours(),                   //小时
        "m+" : this.getMinutes(),                 //分
        "s+" : this.getSeconds(),                 //秒
        "q+" : Math.floor((this.getMonth()+3)/3), //季度
        "S"  : this.getMilliseconds()             //毫秒
    };
    if(/(y+)/.test(fmt)) {
        fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
    }
    for(var k in o) {
        if(new RegExp("("+ k +")").test(fmt)){
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
        }
    }
    return fmt;
}